using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using ProjectNoClue.Graphics;

namespace ProjectNoClue
{
	//TODO: Replace With real statemanager class
	public class ScreenManager : Microsoft.Xna.Framework.Game
	{
		GraphicsDeviceManager graphics;
		public LineBatch draw;

		public SpriteBatch sb;
		public SpriteFont font;

        //Part test;

		int frameRate = 0;
		int frameCounter = 0;
		public TimeSpan elapsedTime = TimeSpan.Zero;

		ResolveTexture2D blurTes;

        List<Screen> screens = new List<Screen>();
        List<Screen> screensToRemove = new List<Screen>();
		
		public ScreenManager()
		{
			graphics = new GraphicsDeviceManager(this);
			Content.RootDirectory = "Content";

			this.IsFixedTimeStep = false;
			graphics.SynchronizeWithVerticalRetrace = false;
			Window.AllowUserResizing = true;

		}

		protected override void Initialize()
		{
			base.Initialize();
		}

		protected override void LoadContent()
		{
			draw = new LineBatch(this);
			sb = new SpriteBatch(GraphicsDevice);
			font = Content.Load<SpriteFont>(@"font");
            //test = Content.Load<Part>("test");

            screens.Add(new LameTestScreen(this));

			Resise(null, null);
		}

		void Resise(object sender, EventArgs e)
		{
			PresentationParameters pp = GraphicsDevice.PresentationParameters;
			if (blurTes != null)
				blurTes.Dispose();

			blurTes = new ResolveTexture2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, 1, pp.BackBufferFormat);
		}

		protected override void UnloadContent()
		{
		}

		string fpsString = "";

		protected override void Update(GameTime gameTime)
		{
			if (Input.OpenMap()) //this was just a test for static stuff, ignore it. Back button exits.
			{
				this.Exit();
			}

			Input.Update();

            foreach (Screen s in screens)
            {
                if (s.IsActive)
                    s.Update(gameTime);
            }
            screens[screens.Count - 1].HandleInput(gameTime);

            RemoveScreens();

			if (elapsedTime > TimeSpan.FromSeconds(1))
			{
				elapsedTime -= TimeSpan.FromSeconds(1);
				frameRate = frameCounter;
				fpsString = frameRate.ToString();
				frameCounter = 0;
			}

			base.Update(gameTime);
		}

		protected override void Draw(GameTime gameTime)
		{
			graphics.GraphicsDevice.Clear(Color.Black);

			draw.Begin();
            sb.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None);
            foreach (Screen s in screens)
            {
                s.Draw(gameTime);
            }
			//draw.Draw(test);
            
			draw.End();

			/*const byte blurAmount = 200;    // higher = more blur

			sb.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
			sb.Draw(blurTes, Vector2.Zero, new Color(255, 255, 255, blurAmount));
			sb.End();

			GraphicsDevice.ResolveBackBuffer(blurTes);

			sb.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
			sb.Draw(blurTes, Vector2.Zero, Color.White);
			sb.End();*/

			frameCounter++;
            //sb.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
			sb.DrawString(font, fpsString, Vector2.Zero, Color.White);
			sb.End();

			base.Draw(gameTime);
		}

        public void AddScreen(Screen s)
        {
            screens.Add(s);
            if (s.IsDominant)
            {
                for (int i = 0; i < screens.Count - 1; i++)
                    screens[i].IsActive = false;
            }
        }

        public void RemoveScreen(Screen s)
        {
            screensToRemove.Add(s);
        }

        public void RemoveScreens()
        {


            while (screensToRemove.Count != 0)
            {
                screensToRemove[screensToRemove.Count - 1].UnloadContent(); //not sure if we even need this...
                screens.Remove(screensToRemove[screensToRemove.Count - 1]);
                screensToRemove.Remove(screensToRemove[screensToRemove.Count - 1]); //remove last screen first?
            }
            if (screens[screens.Count - 1].IsDominant) //if new top screen is dominant, don't activate others
                screens[screens.Count - 1].IsActive = true;
            else //top screen isn't dominant
            { 
                //At this point in development, I'm not sure
                //whether or not it is possible for a dominant screen to be under a non-dominant....
                //so for now, if the top screen isn't dominant, we will assume everything underneath is "active"
                //we can change this later if we see an instance where a non-dominant can lie on top of a dominant.
                foreach (Screen scr in screens)
                    scr.IsActive = true;

            }
        }
	}
}
